package annotation;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 注解工具类.
 *
 * @author guanweichen
 * @version 2010-3-18,下午12:48:47
 */
public class AnnotationUtil {
	/** <注解值名称,注解值> */
	Map<String, Object> mapClassAnnoValue = new HashMap<String, Object>();
	/** <注解值名称,注解值> */
	Map<String, Object> mapReadMethodAnnoValue = new HashMap<String, Object>();
	
	/** <注解名,注解对象> */
	Map<String, Object> mapClassAnno = new HashMap<String, Object>(); 
	/** <注解名,注解对象> */
	Map<String, Object> mapReadMethodAnno = new HashMap<String, Object>();
	
	/**
	 * 得到类注解和Read方法注解.
	 * 
	 * @param clazz
	 * @throws IntrospectionException
	 */
	public void getInfoAnnotations(Class<?> clazz) throws IntrospectionException {
		
		Annotation[] annotations = clazz.getAnnotations();// 类的注解
		for (Annotation annotation : annotations) {
			putAnnotations(annotation, true);
		}
		PropertyDescriptor[] descriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
		for (PropertyDescriptor propertyDescriptor : descriptors) {
			if (!propertyDescriptor.getName().equals("class")) {
				Method method = propertyDescriptor.getReadMethod();// read方法的注解
				Annotation[] readMethodAnnotations = method.getAnnotations();//还可以用method.getDeclaredAnnotations()
				for (Annotation annotation : readMethodAnnotations) {
					putAnnotations(annotation, false);
				}
			}
		}
	}
	
	private void putAnnotations(Annotation annotation, boolean off){
		if (off) {
			mapClassAnno.put(annotation.annotationType().getName(), annotation);
		} else {
			mapReadMethodAnno.put(annotation.annotationType().getName(), annotation);
		}
	}
	
	/**
	 * 暂时不知道怎么处理,得到类注解和Read方法注解中的注解值和名称.
	 * 
	 * @param clazz
	 * @throws IntrospectionException
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	public void getInfoAnnoValues(Class<?> clazz) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException{
		
		Annotation[] annotations = clazz.getAnnotations();// 类的注解
		for (Annotation annotation : annotations) {
			
			for (Method m : annotation.annotationType().getDeclaredMethods()) {
				mapClassAnnoValue.put(m.getName(), m.invoke(annotation, null));
			}
		}
		PropertyDescriptor[] descriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
		for (PropertyDescriptor propertyDescriptor : descriptors) {
			if (!propertyDescriptor.getName().equals("class")) {
				Method method = propertyDescriptor.getReadMethod();// read方法的注解
				Annotation[] readMethodAnnotations = method.getAnnotations();//还可以用method.getDeclaredAnnotations()
				for (Annotation annotation : readMethodAnnotations) {
					for (Method m : annotation.annotationType().getDeclaredMethods()) {
						mapReadMethodAnnoValue.put(m.getName(), m.invoke(annotation, null));
					}
				}
			}
		}
	}
}
